//---------------------------------------------------------------------------------
// Copyright (c) 2011, Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//---------------------------------------------------------------------------------

namespace Microsoft.ServiceBus.Samples
{
    using System;
    using System.Collections.Generic;
    using Microsoft.ServiceBus;
    using Microsoft.ServiceBus.Description;
    using Microsoft.ServiceBus.Messaging;

    public class Receiver
    {
        private static string serviceBusNamespace;
        private static string serviceBusIssuerName;
        private static string serviceBusIssuerKey;

        public static void Main()
        {
            // Setup:
            GetUserCredentials();
            QueueClient queueClient = CreateQueueClient("OrdersQueue");

            // Read messages from queue until queue is empty:
            Console.WriteLine("Reading messages from queue...");

            List<long> deferredSequenceNumbers = new List<long>();
         
            while (true)
            {
                BrokeredMessage receivedMessage = queueClient.Receive(TimeSpan.FromSeconds(10));

                if (receivedMessage == null)
                {
                    break;
                }
                else
                {
                    // Low-priority messages will be dealt with later:
                    if (receivedMessage.Properties["Priority"].ToString() == "Low")
                    {
                        receivedMessage.Defer();
                        Console.WriteLine("Deferred message with id {0}.", receivedMessage.MessageId);
                        // Deferred messages can only be retrieved by message receipt. Here, keeping track of the
                        // message receipt for a later retrieval:
                        deferredSequenceNumbers.Add(receivedMessage.SequenceNumber);
                    }
                    else
                    {
                        ProcessMessage(receivedMessage);
                    }
                }
            }

            Console.WriteLine();
            Console.WriteLine("No more messages left in queue. Moving onto deferred messages...");

            // Process the low-priority messages:
            foreach (long sequenceNumber in deferredSequenceNumbers)
            {
                ProcessMessage(queueClient.Receive(sequenceNumber));
            }

            Console.WriteLine();
            Console.WriteLine("Press [Enter] to exit.");
            Console.ReadLine();
        }

        private static void GetUserCredentials()
        {
            // User namespace
            Console.WriteLine("Please provide the namespace to use:");
            Receiver.serviceBusNamespace = Console.ReadLine().Trim();

            // Issuer name
            Console.WriteLine("Please provide the Issuer name to use:");
            Receiver.serviceBusIssuerName = Console.ReadLine().Trim();

            // Issuer key
            Console.WriteLine("Please provide the Issuer key to use:");
            Receiver.serviceBusIssuerKey = Console.ReadLine().Trim();
        }


        // Create the runtime entities (queue client)
        private static QueueClient CreateQueueClient(string queueName)
        {
            Uri runtimeUri = ServiceBusEnvironment.CreateServiceUri("sb", Receiver.serviceBusNamespace, string.Empty);
            
            MessagingFactory messagingFactory = MessagingFactory.Create(
                runtimeUri,
                TokenProvider.CreateSharedSecretTokenProvider(Receiver.serviceBusIssuerName, Receiver.serviceBusIssuerKey));

            return messagingFactory.CreateQueueClient(queueName);
        }

        private static void ProcessMessage(BrokeredMessage message)
        {
            Console.WriteLine("Processed {0}-priority order {1}.", message.Properties["Priority"], message.MessageId);
            message.Complete();
        }
    }
}
